18.1 入门项目
说明:
18.2 KVC简介
说明:通过
键/值编码(KVC)
,没有相应getter
方法也能获取属性值,没有相应setter
方法也能设置属性值。
自动开箱和装箱:仅KVC
具有这种功能,常规方法调用和属性语法不具备该功能。
valueForKey实例方法
说明:将属性名作为
键
获取属性的值
。
原理:在Objective-C
的运行中使用元数据打开对象并进入其中查找需要的信息,查找顺序为
- 以参数命名(
key
或isKey
)的getter
- 名称为
_key
或key
的实例变量自动装箱:通过该方法获取属性值时,如果属性为
标量(int、float、struct)
,该方法会根据需要将属性放入NSNumber
或NSValue
中。
兼容性:在C
或C++
中不能执行这种操作。
原型:NSKeyValueCoding.h
1 | /** |
setValue:forkey实例方法
说明:将属性名作为
键
设置属性的值
。
自动开箱:使用该方法设置属性时,如果属性是标量(int、float、struct)
,则会从新值(id
)中提取出和属性类型相符的标量
。
技巧:如果想设置一个标量
值,在调用setValue
方法之前需要将它们包装掐来(封装到对象中)。
原型:NSKeyValueCoding.h
1 | /** |
1 | // 创建 Car 对象 |
18.3 键路径
说明:进行
get
和set
操作,除了通过键
,还可以通过键路径
。键路径
可以根据对象图
访问到任意深度的对象,比使用一系列嵌套方法调用更容易访问到对象。
valueForKeyPath实例方法
说明:将属性名作为
键
获取属性的值
。
原型:NSKeyValueCoding.h
1 | /** |
setValue:forKeyPath实例方法
说明:将属性名作为
键
设置属性的值
。
原型:NSKeyValueCoding.h
1 | /** |
1 | // 通过 KVC 设置车的引擎的马力 |
18.4 整体操作
说明:如果使用
键值
或键路径
访问位于对象中的数组类型的实例属性
的元素,实际上会对数组中所有元素进行操作。如果是查询操作,则还会将查询结果打包到另一个数组中并返回。
注意:这种整体操作
意味着无法在键路径
中单独索引数组类型的属性的其中一个元素。
1 | // 通过 KVC 访问车的轮胎的胎压,会便利tires的每个属性,并将所有tires的属性的pressure变量封装到 NSNumber 对象中并返回 |
18.4.1 休息一下
说明:创建一个新的类用于后面的学习使用。
Garage.h
1 |
|
Garage.m
1 |
|
main.m
1 | // 汽车集合 |
18.4.2 快速运算
说明:
键路径
中可以使用进行引用一些运算符进行一些运算,比如
- prevProperty.
@count
:计算 prevProperty 包含的对象的总数- prevProperty.
@sum
.nextProperty:计算prevProperty包含的所有对象的nextProperty属性的总和- prevProperty.
@avg
.nextProperty:计算prevProperty包含的所有对象的nextProperty属性的平均值- prevProperty.
@max
.nextProperty:计算prevProperty包含的所有对象的nextProperty属性的最大值- prevProperty.
@min
.nextProperty:计算prevProperty包含的所有对象的nextProperty属性的最小值- prevProperty.
@distinctUnionOfObjects
.nextProperty:获得从prevProperty包含的所有对象的nextProperty属性构成的集合去重后的集合注意:不要滥用
KVC
通过键路径
提供的处理集合类的快速运算
特性,因为
- 速度比较慢
- 编译器无法对它进行错误检查(出现运行时错误时才能发觉)
限制:无法添加自定义的运算符
1 | // @count |
18.5 批处理
说明:
KVC
提供了对对象进行批量操作的方式。
setValuesForKeysWithDictionary实例方法
说明:通过
字典
对对象进行批量set
。
原型:NSKeyValueCoding.h
1 | /** |
dictionaryWithValuesForKeys实例方法
说明:通过
数组
对对象进行批量set
原型:NSKeyValueCoding.h
1 | /** |
1 | // 获取汽车集合中的最后一个汽车实例 |
18.6 nil 仍然可用
背景:默认情况下,应用
KVC
调用setValue:forKey
设置某个属性的值为nil
时,编译器会给出警告。
解决:可以通过重写setNilValueForKey
方法给出有意义个返回值而避免警告。
扩展:这里的nil
是标量nil
,不要和[NSNull null]
相混淆
1 | - (void) setNilValueForKey: (NSString *) key { |
1 | // 会将 mileage 设置为 0 |
18.7 处理未定义键
背景:如果
KVC
机制无法找到处理方法,会退回并询问该如何处理。默认的实现会取消操作。
解决:通过重写setValue:forUndefinedKey
和valueForUndefinedKey
更改默认行为,使对象可以设置和获取任何键。
1 | /** |